import {getToken, removeToken, setToken} from "../../utils/auth";
import {authenticate} from "../../api/auth";
import {getUser} from "../../api/users";
import jwt from 'jsonwebtoken';

const state = {
  token: getToken(),
  payload: {
    exp: null,
    iat: null,
    rol: null,
    sub: null,
    user_id: null
  },
  info: {
    id: null,
    username: null,
    password: null,
    age: null,
    sex: null,
    nickname: null,
    realName: null,
    mobile: null,
    address: null,
    admin: false,
    avatar: null,
    registerTime: null,
    updateTime: null,
    userType: null,
    suspended: null,
  },
};

const mutations = {
  set_token: (state, token) => {
    if (token) {
      state.token = token;
      setToken(token);
    }
    else {
      state.token = null;
      removeToken();
    }
  },
  set_payload: (state, payload) => {
    if (payload) state.payload = payload;
    else Object.keys(state.payload).forEach(k => state.payload[k] = null);
  },
  set_user: (state, user) => {
    if (user) {
      Object.keys(state.info).forEach(k => state.info[k] = user[k]);
    }
    else Object.keys(state.info).forEach(k => state.info[k] = null);
  }
};

const actions = {
  logout({commit}) {
    commit('set_token', null);
    commit('set_payload', null);
    commit('set_user', null);
  },
  login({commit, dispatch}, userInfo) {
    return new Promise((resolve, reject) => {
      const {username, password} = userInfo;
      authenticate(username, password).subscribe(async response => {
        if (response.data) {
          const {token} = response.data;
          if (token) {
            commit('set_token', token);
            const user = await dispatch('getUser').catch(err => {
              reject(err);
            });
            resolve(user);
          }
          else {
            resolve(null);
          }
        }
        else resolve(null);
      }, error => {
        if (error.response && error.response.data) {
          switch (error.response.data.message) {
            case 'INVALID_CREDENTIALS':
            case 'USERNAME_NOT_FOUND':
              resolve(null);
              break;
            default:
              reject(error.response.data)
          }
        }
        else reject(error);
      });
    });
  },
  getUser({commit, state}) {
    return new Promise((resolve, reject) => {
      if (!state.token) resolve(null);
      if (!state.payload.user_id) {
        const payload = jwt.decode(state.token);
        commit('set_payload', payload);
      }
      const userId = state.payload.user_id;
      if (!userId) reject('Invalid user id: ' + userId);
      // if (state.info.id) resolve(state.info);
      getUser(userId).subscribe(response => {
        if (response.data) {
          commit('set_user', response.data);
          resolve(response.data);
        }
        else resolve(null);
      }, error => {
        reject(error);
      })
    })
  }
};

export default {
  namespaced: true,
  state, mutations, actions
}
